package cn.tedu.rabbitmq.test;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

/**
 * 声明组件、创建交换机、创建队列
 */
public class Declare {
    private Channel channel;
    // @Before 是在所有的单元测试test方法之前执行
    @Before
    public void initChannel() throws IOException, TimeoutException {
        // 通过java客户端建立和rabbitmq的连接
        ConnectionFactory factory = new ConnectionFactory();
        // 给工厂提供连接属性 ip:port
        factory.setHost("192.168.8.100");
        factory.setPort(5672);
        // 权限账号 admin/123456
        factory.setUsername("admin");
        factory.setPassword("123456");
        // 虚拟主机：每个连接工厂由一个程序管理，程序所属的环境 连接的虚拟主机virtual_host不同
        // 实现不同环境的数据隔离 默认就是/
        factory.setVirtualHost("/");
        Connection connection = factory.newConnection();
        // 可以从长连接获取短链接
        channel = connection.createChannel();
    }
    @Test
    public void queueDeclare() throws IOException {
        // 创建队列
        channel.queueDeclare("queue2", true, false, false, null);
        /* String queue: 创建的队列名称，在虚拟机中只能存在唯一名称
        *  boolean durable: 是否持久化，持久化之后，true在重启rabbitmq，队列还在
        *  boolean exclusive: 是否独占队列，独占队列，只能被一个消费者消费，true别的连接无法操作队列 false所有连接都可以操作队列
        *  boolean autoDelete: 队列是否自动删除 true队列从第一个监听消费者开始计算，到最后一个消费者断开连接，自动删除 false不删除
        *  Map<String, Object> args: 队列特性参数 value三种 String (long double integer) boolean
        *  key值是固定的，可以表示rabbitmq声明队列的特性，比如队列最大长度（最多可以容纳多少个消息）
        * */
    }
    @Test
    public void queueDeclareArgs() throws IOException {
        /*
         * 队列最大未使用时间
         * x-expires=10000
         * x-max-length=10 默认drop head
         */
        Map<String,Object> args=new HashMap<>();
        args.put("x-expires",10000);
        args.put("x-max-length",10);
        channel.queueDeclare("queue3",false,false,false,args);
    }
    @Test
    public void exchangeDeclare() throws IOException {
        channel.exchangeDeclare("direct_01","direct",false,false,null);
        /* String exchange: 交换机名称，名称唯一
        *  String type:交换机类型 direct fanout topic header
        *  boolean durable: 交换机是否持久化 true持久化 false不持久化
        *  boolean autoDelete: 交换机是否自动删除 true自动删除 false不自动删除
        *  Map<String, Object> arguments: 交换机特性参数 比如是否直接还是间接交换机
        * */
        channel.queueBind("queue1","direct_01","南京");
    }
    @Test
    public void exchangeDeclareFanout() throws IOException {
        channel.exchangeDeclare("fanout_01","fanout",false,false,null);
        channel.queueBind("queue1","fanout_01","南京");
        channel.queueBind("queue2","fanout_01","长三角");
    }
    @Test
    public void exchangeDeclareTopic() throws IOException {
        channel.exchangeDeclare("topic_ex_01","topic",false,false,null);
        // queue01 queue02使用明确的路由绑定
        channel.queueBind("queue1","topic_ex_01","南京");
        channel.queueBind("queue2","topic_ex_01","长三角");
        channel.exchangeDeclare("topic_ex_02","topic",false,false,null);
        // 使用统配符号 #: 通配符,匹配任意长度,任意多级的字符串.(范围大)
        //            *: 通配符,匹配任意长度的字符串,但是只能匹配一级.(范围小)
        channel.queueBind("queue1","topic_ex_02","*.南京.*");
        channel.queueBind("queue2","topic_ex_02","*.长三角.#");
    }
}
